package com.cyou.weplay.db;

import com.cyou.weplay.shard.ShardManager;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.sql.DataSource;

import com.alibaba.dubbo.common.utils.StringUtils;

/**
 * TableShardManager
 *
 * @author zhaomingyu
 */
public class TableShardManager extends ShardManager<TableShardPlan, TableShardInfo> {

    Map<String, TreeMap<Long, TableShardInfo>> shardedTableMap = new HashMap<String, TreeMap<Long, TableShardInfo>>();

    @Override
    public void init() {
        if (shardPlanList == null) {
            return;
        }
        for (TableShardPlan shardPlan : shardPlanList) {
            List<TableShardGroup> shardGroupList = shardPlan.getShardGroupList();
            String planTableName = shardPlan.getTableName();
            for (TableShardGroup shardGroup : shardGroupList) {
                String tableName = planTableName;
                if (!StringUtils.isEmpty(shardGroup.getTableName())) {
                    tableName = shardGroup.getTableName();
                }
                String shardKey = shardGroup.getShardKey();
                DataSource ds = shardGroup.getDatasource();
                TreeMap<Long, TableShardInfo> shardInfoMap = shardedTableMap.get(tableName);
                if (shardInfoMap == null) {
                    shardInfoMap = new TreeMap<Long, TableShardInfo>();
                    shardedTableMap.put(tableName, shardInfoMap);
                }
                int minSeq = shardGroup.getMinSeq();
                int maxSeq = shardGroup.getMaxSeq();
                for (int i = minSeq; i <= maxSeq; i++) {
                    String shardedName = tableName + "_" + i;
                    for (int j = 0; j < 10; j++) {
                        shardInfoMap.put(hash(shardKey + "-" + shardedName + "-" + j), new TableShardInfo(shardKey, ds, shardedName));
                    }
                }
            }
        }

    }

    public TableShardInfo getShardInfo(String tableName, String id) {
        long hash = hash(id);
        TreeMap<Long, TableShardInfo> shardInfoMap = shardedTableMap.get(tableName);
        if (shardInfoMap == null) {
            return defaulShard;
        }
        SortedMap<Long, TableShardInfo> tail = shardInfoMap.tailMap(hash);
        if (tail.isEmpty()) {
            return shardInfoMap.get(shardInfoMap.firstKey());
        }
        return tail.get(tail.firstKey());
    }

}
